package com.kehutong.admin.controler;

import com.kehutong.admin.entity.Menu;
import com.kehutong.admin.enums.AppType;
import com.kehutong.admin.enums.MenuType;
import com.kehutong.admin.enums.RedirectType;
import com.kehutong.admin.service.UserHelper;
import com.kehutong.admin.util.TreeEntityUtil;
import com.kehutong.admin.util.TreeUtil;
import com.kehutong.common.util.Token;
import org.coraframework.authz.HasPermission;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.ActionResult;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.util.Objects;

import java.util.*;

@MvcAction
@ReqMapping("/admin/sys/menu")
public class MenuController {
	static final Logger logger = LoggerFactory.getLogger(MenuController.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private UserHelper userHelper;

    @ReqMapping(value = "/tree")
    public ActionResult<String> listAsTree(Token token, JSONObject jsonObject) throws Exception {
//    	Menu root = UserUtils.getMenuTree(true, true);
    	Menu root = userHelper.menuTree(token.getRoles(), true);
        return Result.success(root);
    }

	@ReqMapping(value = "/list")
	public Object list(Token token) throws Exception {
		Set<String> ids = userHelper.getTopMenuIds(token.getRoles());

		List<Menu> list = jdbcSession.findArray(Menu.class).in("id", ids)
				.eq("deleted", false)
				.exe();

		return Result.success(list);
	}

	@ReqMapping(value = "/groupList")
	public Object groupList(Token token, JSONObject jsonObject) throws Exception {
    	logger.info("MenuController.groupList--------------------------------------------begin;param:{}",jsonObject);
		List<Map<String,Object>> result = new ArrayList<>();
    	try {
			Set<String> menuIds = userHelper.getTopMenuIds(token.getRoles());
			logger.info("MenuController.groupList--------------------------------------------111111111111111end;result:{}",result);
			FindArray<Menu> find = jdbcSession.findArray(Menu.class)
					.in("id", menuIds)
					.eq("deleted", false)
					.order("sort", "desc");
			logger.info("MenuController.groupList--------------------------------------------222222222222end;result:{}",result);
//		 if(Objects.nonEmpty(jsonObject.getString("isSetting")) && jsonObject.getBoolean("isSetting")){
//		 	find.noEq("id", "04d32d1188cc467eb7a6f363bb23760a");
//		 }

			List<Menu> list = find.exe();
			logger.info("MenuController.groupList--------------------------------------------222222222222.5end;result:{}",list);
			logger.info("MenuController.groupList--------------------------------------------333333333333end;result:{}",result);
			for (AppType type: AppType.values()) {
				Map<String,Object> json = new LinkedHashMap<>();
				json.put("groupName", type.getDesc());
				json.put("id", type.getId());

				List<Menu> apps = new LinkedList<>();

				for(Menu item:list){
					if(java.util.Objects.equals(item.getAppType(), type.getId())){
						apps.add(item);
					}
				}
				logger.info("MenuController.groupList|apps:{}",apps);
				json.put("apps", apps);

				if(apps.size() > 0){
					result.add(json);
				}
				logger.info("MenuController.groupList-----------json:{}",json);
			}
			logger.info("MenuController.groupList--------------------------------------------end;result:{}",result);
			return result;
		}catch (Exception e){
			logger.error("MenuController.groupList is error:",e);
		}


       return result;
	}

	public static void main(String[] args) {
		List<JSONObject> result = new ArrayList<>();
		JSONObject json = new JSONObject();
		json.put("groupName","222");
		json.put("id","343434");
		result.add(json);
		System.out.println(Objects.toString(result));
	}

	@ReqMapping("/getMenuSubdivide")
	public Object getMenuSubdivide(Token token, JSONObject jsonObject) throws Exception {
    	String id = jsonObject.getString("id");

		Set<String> ids = userHelper.getMenuIds(token.getRoles(), true);

		List<Menu> menus = jdbcSession.findArray(Menu.class)
				.markBegin()
				.like("parent_ids", id).or()
				.eq("id", id)
				.markEnd().and()
				.in("id", ids)
				.exe();

		Menu root = TreeEntityUtil.organizeAsTree(menus, id);

    	return Result.success(root);
	}

	@ReqMapping(value = "/listById")
	public Object listById(JSONObject jsonObject) throws Exception {
		List<Menu> list = jdbcSession.findArray(Menu.class).in(jsonObject, "parent_id")
				.eq("deleted", false)
				.exe();

		return Result.success(list);
	}

    @HasPermission("sys:menu:view")
    @ReqMapping("/get")
    public ActionResult<String> getById(JSONObject jsonObject) {
    	Menu item = Pool.get(Menu.class, jsonObject.getString("id"));
    	if (Objects.isNull(item) || item.isDeleted()) {
    		return Result.error(1003, "菜单不存在");
    	}
    	
    	if (Objects.nonEmpty(item.getParent_id())) {
    		item.setParent(Pool.get(Menu.class, item.getParent_id()));
    	}
    	
    	return Result.success(item);
    }

    @HasPermission("sys:menu:edit")
    @ReqMapping("/save")
    public ActionResult<String> save(JSONObject jsonObject) {
    	Menu item = Pool.newInstance(Menu.class);
    	setProperty(item, jsonObject);
    	jdbcSession.insert(item);
		
        return Result.success();
    }
    
    @HasPermission("sys:menu:edit")
    @ReqMapping("/update")
    public ActionResult<String> update(JSONObject jsonObject) throws Exception {
    	Menu item = Pool.get(Menu.class, jsonObject.getString("id"));
    	setProperty(item, jsonObject);
		jdbcSession.updateById(item);
    	
		changeChildId(item);
//		UserUtils.getMenuTree(true, true);
        return Result.success();
    }
    
    @HasPermission("sys:menu:edit")
    @ReqMapping("/delete")
    public ActionResult<String> deleteById(JSONObject jsonObject) {
    	Menu item = Pool.get(Menu.class, jsonObject.getString("id"));
		item.setDeleted(true);
        
		jdbcSession.updateById(item);
    	
        return Result.success();
    }

	@ReqMapping("/enums")
	public Object getEnums() {
		Map<String, Object> map = new HashMap<>();
		map.put("appTypes", Arrays.asList(AppType.values()));
		map.put("menuTypes", Arrays.asList(MenuType.values()));
		map.put("redirectTypes", Arrays.asList(RedirectType.values()));
		return Result.success(map);
	}

    @HasPermission("sys:menu:edit")
    @ReqMapping("/sort")
    public ActionResult<String> sort(JSONObject jsonObject) {
    	Menu menu = Pool.get(Menu.class, jsonObject.getString("id"));
    	menu.setSort(jsonObject.getInteger("sort"));
    	
    	jdbcSession.updateById(menu);
        return Result.success();
    }
    
    private void changeChildId(Menu parent) {
 		List<Menu> itemList = jdbcSession.findArray(Menu.class)
 				.like("parent_ids", parent.getId())
 				.exe();
 		
 		for (Menu item : itemList) {
 			item.setParent_ids(TreeUtil.getParentIds(item));
 		}
 		
 		jdbcSession.updateById(itemList);
 	}
    
    private void setProperty(Menu item, JSONObject jsonObject) {
 		item.setName(jsonObject.getString("name"));
 		item.setIcon(jsonObject.getString("icon"));
 		item.setHref(jsonObject.getString("href"));
 		item.setPermission(jsonObject.getString("permission"));

 		String sort = jsonObject.getString("sort");
 		if(Objects.isEmpty(sort)){
			sort = "30";
		}
 		item.setSort(Integer.valueOf(sort));
 		item.setTarget(jsonObject.getString("target"));
 		item.setDeleted(false);
		item.setShow(jsonObject.getInteger("show"));
 		item.setParent_id(jsonObject.getString("parent_id"));
 		item.setParent_ids(TreeUtil.getParentIds(item));
 		item.setRemarks(jsonObject.getString("remarks"));
		item.setAppType(jsonObject.getString("appType"));
		item.setMenuType(jsonObject.getString("menuType"));
		item.setRedirectType(jsonObject.getString("redirectType"));
 		item.setFileId(jsonObject.getString("fileId"));
 		item.setIdentify(jsonObject.getString("identify"));
 		item.setActive(jsonObject.getString("active"));
 		item.setEntry(jsonObject.getString("entry"));
 	}
}
